/* Copyright (c) 2011 Timothée Lacroix
 * This file is part of HINAPT.
 *
 * HINAPT is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * HINAPT is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with HINAPT.  If not, see <http://www.gnu.org/licenses/>.
 */

/*!
  \file thresholdFeature.hpp
  Implémentation des classifieurs faibles composant les Classifieurs
 */

#ifndef THFEATURE_HPP_INCLUDED
#define THFEATURE_HPP_INCLUDED

#include "_trainer.hpp"

/*!
  Représente une Feature
 */
struct Feature{
  /*!
    le type de Feature
  */
  int numero;
  /*!
    Coordonnée du rectangle de la Feature
  */
  int x1;
  /*!
    Coordonnée du rectangle de la Feature
  */
  int y1;
  /*!
    Coordonnée du rectangle de la Feature
  */
  int x2;
  /*!
    Coordonnée du rectangle de la Feature
  */
  int y2;
  /*!
    \param n numéro
    \param x x1
    \param y y1
    \param _x x2
    \param _y y2
  */
  Feature(int n=0,int x=0,int y=0,int _x=0,int _y=0){
    numero=n;x1=x;y1=y;x2=_x;y2=_y;
  }
  /*!
    \param output flux de sortie pour la sauvegarde de la Feature
    \return retourne true si l'écriture s'est bien passée, false sinon
  */
  bool save(ostream &output){
    output<<numero<<" "<<x1<<" "<<y1<<" "<<x2<<" "<<y2<<" ";
    return !(output.fail());
  }
  /*!
    \param output flux d'entrée pour le chargement de la Feature
    \return retourne true si la lecture s'est bien passée, false sinon
  */
  bool load(istream &input){
    input>>numero;
    input>>x1;
    input>>y1;
    input>>x2;
    input>>y2;
    return !(input.fail());
  }
};
/*!
  Représente un Triplet (evaluation,valeur,poids) ainsi que l'ordre sur ce
  triplet
*/
struct Triplet{
  int evaluation;
  int val;
  double poids;
  bool operator<(const Triplet &a)const;
  Triplet(int e,int v,double p){evaluation=e;val=v;poids=p;}
  Triplet(){}
};

/*!
  Représente une ThFeature (thresholded feature)
*/
class ThFeature
{
public:
  /*!
    la Feature
  */
  Feature f;
  /*!
    le seuil appliqué à la Feature
  */
  double threshold;
  /*!
    polarité du seuil
  */
  bool inf;

  ThFeature(){f=Feature(0,0,0,0,0);threshold=0;inf=false;}
  ThFeature(Feature a,double t,bool i){f=a;threshold=t;inf=i;}
  /*!
    Construit la  ThFeature, en choisissant le meilleur seuil (celui qui
    minimise l'erreur empirique)
    \param a Feature
    \param pos exemples positifs d'entrainement
    \param neg exemples négatifs d'entrainement
    \param poids les poids des exemples d'entrainement (positifs puis négatifs)
  */
  ThFeature(Feature a,vector<Mat> &pos,vector<Mat> &neg,vector<double> &poids);
  /*!
    \param output flux de sortie pour la sauvegarde de la ThFeature
    \return retourne true si l'écriture s'est bien passée, false sinon
  */
  bool save(ostream &output);
  /*!
    \param output flux d'entrée pour le chargement de la ThFeature
    \return retourne true si la lecture s'est bien passée, false sinon
  */
  bool load(istream &input);
  /*!
    \param pos exemples positifs d'entrainement
    \param neg exemples négatifs d'entrainement
    \param poids les poids des exemples d'entrainement (positifs puis négatifs)
    \param print affiche ou non l'erreur trouvée
    \return renvoit l'erreur empirique de la ThFeature
  */
  double error(vector<Mat>& pos,vector<Mat>& neg,
               vector<double>& poids,bool print=false);

  /*!
    \param img l'image intégrale sur laquelle on évalue la ThFeature
    \param weight permet de pondérer l'évaluation des features, pour que les
            seuils calculés sur les images d'entrainement correspondent
    \return 1 si l'évaluation est positive, -1 sinon
  */
  int eval(Mat img,double weight=1);
};
#endif // DETECTOR_HPP_INCLUDED
